package com.newasia.management.services;

import com.newasia.commons.tool.exception.ValidateException;
import com.newasia.management.ISysRoleService;
import com.newasia.management.constants.ManagementRetCode;
import com.newasia.management.converter.SysMenuConverter;
import com.newasia.management.converter.SysRoleConverter;
import com.newasia.management.dal.user.entitys.SysRole;
import com.newasia.management.dal.user.entitys.SysRoleMenu;
import com.newasia.management.dal.user.entitys.SysUser;
import com.newasia.management.dal.user.entitys.SysUserRole;
import com.newasia.management.dal.user.persistence.SysMenuMapper;
import com.newasia.management.dal.user.persistence.SysRoleMapper;
import com.newasia.management.dal.user.persistence.SysRoleMenuMapper;
import com.newasia.management.dal.user.persistence.SysUserMapper;
import com.newasia.management.dto.user.*;
import com.newasia.management.dto.user.role.*;
import com.newasia.management.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class SysRoleServiceImpl implements ISysRoleService {

    @Autowired
    SysRoleMapper sysRoleMapper;

    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    SysMenuMapper sysMenuMapper;

    @Autowired
    SysRoleMenuMapper sysRoleMenuMapper;

    @Autowired
    SysMenuConverter sysMenuConverter;

    @Autowired
    SysRoleConverter sysRoleConverter;

    @Override
    public List<SysRoleDto> selectSysRoleByUserId(Long user_id) {
        log.info("Begin SysRoleServiceImpl.selectSysRoleByUserId: user_id:"+user_id);

        List<SysRoleDto> sysRoleDtoList = new ArrayList<SysRoleDto>();
        SysUser sysUser = new SysUser();
        sysUser.setUserId(user_id);
        try{
            List<SysRole> sysRoles = sysRoleMapper.selectSysRoleByUserId(sysUser);
            if(sysRoles.size()<0){
                return null;
            }
            sysRoleDtoList = sysRoleConverter.role2List(sysRoles);
        }catch (Exception e){
            log.error("SysRoleServiceImpl.selectSysRoleByUserId Occur Exception :"+e);
        }

        return sysRoleDtoList;
    }

    @Override
    public RoleUserResponse insertSysUserRole(RoleUserRequest request) {
        log.info("Begin SysRoleServiceImpl.insertSysUserRole: request:"+request);
        RoleUserResponse response=new RoleUserResponse();
        response.setCode(ManagementRetCode.SUCCESS.getCode());
        response.setMsg(ManagementRetCode.SUCCESS.getMessage());
        try {
            SysUser user = sysUserMapper.selectUserByName(request.getUserNmae());
            SysUserRole userRole = new SysUserRole();
            userRole.setRoleId(request.getRoleId());
            userRole.setUserId(user.getUserId());

            //validUserRole(user,role);
            sysRoleMapper.insertSysUserRole(userRole);
        }catch (Exception e){
            log.error("SysRoleServiceImpl.insertSysUserRole Occur Exception :"+e);
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            response.setCode(ManagementRetCode.SYSTEM_ERROR.getCode());
            response.setMsg(ManagementRetCode.SYSTEM_ERROR.getMessage());
        }
        return response;
    }

    @Override
    public RoleUserResponse updateSysUserRole(RoleUserRequest roleUserRequest) {
        log.info("Begin SysRoleServiceImpl.updateSysUserRole: request:"+roleUserRequest);
        RoleUserResponse response=new RoleUserResponse();
        try {
            SysUser user = sysUserMapper.selectUserByName(roleUserRequest.getUserNmae());
            SysRole role = sysRoleMapper.selectByPrimaryKey(roleUserRequest.getRoleId());

            SysUserRole userRole = new SysUserRole();
            userRole.setRoleId(role.getRoleId());
            userRole.setUserId(user.getUserId());

            validUserRole(user,role);
            if(sysRoleMapper.updateSysRoleByUserId(userRole)!=1){
                response.setCode(ManagementRetCode.ROLE_UPDATE_ERROR.getCode());
                response.setMsg(ManagementRetCode.ROLE_UPDATE_ERROR.getMessage());
                return response;
            }
            response.setCode(ManagementRetCode.SUCCESS.getCode());
            response.setMsg(ManagementRetCode.SUCCESS.getMessage());
        }catch (Exception e){
            log.error("SysRoleServiceImpl.updateSysUserRole Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            response.setCode(ManagementRetCode.SYSTEM_ERROR.getCode());
            response.setMsg(ManagementRetCode.SYSTEM_ERROR.getMessage());
        }
        return response;
    }

    @Override
    public SysRoleListResponse selectSysRoleList(SysRoleListRequset requset) {
        log.info("Begin SysRoleServiceImpl.selectSysRoleList: request:"+requset);
        SysRoleListResponse response = new SysRoleListResponse();
        response.setCode(ManagementRetCode.SUCCESS.getCode());
        response.setMsg(ManagementRetCode.SUCCESS.getMessage());

        try {
            List<SysRole> roleList = new ArrayList<SysRole>();
            SysRole role = new SysRole();
            if(requset.getRoleId()==null)
                roleList = sysRoleMapper.selectSysRole();
            else{
                role = sysRoleMapper.selectByPrimaryKey(requset.getRoleId());
                if(role==null||role.equals("")){
                    response.setCode(ManagementRetCode.ROLE_NOT_EXIST.getCode());
                    response.setMsg(ManagementRetCode.ROLE_NOT_EXIST.getMessage());
                    return response;
                }
                roleList.add(role);
            }
            List<RoleMenuListDto> dtos = sysRoleConverter.roleMenuList2List(roleList);
            dtos.parallelStream().forEach(dto->{
                dto.setSysMenuList(sysMenuConverter.menu2List(
                        sysMenuMapper.selectSysMenuByRoleId(dto.getRoleId())));
            });
            response.setSysRoleDtoList(dtos);
        }catch (Exception e){
            log.error("SysRoleServiceImpl.selectSysRoleList Occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            response.setCode(ManagementRetCode.SYSTEM_ERROR.getCode());
            response.setMsg(ManagementRetCode.SYSTEM_ERROR.getMessage());
        }
        return response;
    }

    @Override
    public UpdateSysRoleResponse updateSysRole(UpdateSysRoleRequset requset) {
        log.info("Begin SysRoleServiceImpl.updateSysRole: request:"+requset);
        UpdateSysRoleResponse response = new UpdateSysRoleResponse();
        requset.requestCheck();
        response.setCode(ManagementRetCode.SUCCESS.getCode());
        response.setMsg(ManagementRetCode.SUCCESS.getMessage());

        try {
            SysRole role = new SysRole();
            role.setRoleId(requset.getRoleId());
            role.setRoleName(requset.getRoleName());
            String roleName = sysRoleMapper.selectByPrimaryKey(requset.getRoleId()).getRoleName();
            if(!requset.getRoleName().equals(roleName)){
                if(sysRoleMapper.selectSysRoleByName(role)!=null){
                    response.setCode(ManagementRetCode.ROLENAME_ALREADY_EXISTS.getCode());
                    response.setMsg(ManagementRetCode.ROLENAME_ALREADY_EXISTS.getMessage());
                    return response;
                }
            }
            sysRoleMapper.updateByPrimaryKeySelective(role);
            sysRoleMenuMapper.deleteByRoleId(requset.getRoleId());
            if(requset.getMenuIds().size()>0){
                requset.getMenuIds().parallelStream().forEach(dto->{
                    SysRoleMenu sysRoleMenu = new SysRoleMenu();
                    sysRoleMenu.setMenuId(dto);
                    sysRoleMenu.setRoleId(requset.getRoleId());
                    sysRoleMenuMapper.insert(sysRoleMenu);
                });
            }

        }catch (Exception e){
            log.info("Begin SysRoleServiceImpl.updateSysRole: request:"+requset);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            e.printStackTrace();
            response.setCode(ManagementRetCode.SYSTEM_ERROR.getCode());
            response.setMsg(ManagementRetCode.SYSTEM_ERROR.getMessage());
        }
        return response;
    }

    @Override
    @Transactional
    public InsertSysRoleResponse insertSysRole(InsertSysRoleRequset requset) {
        log.info("Begin SysRoleServiceImpl.insertSysRole: request:"+requset);
        InsertSysRoleResponse response = new InsertSysRoleResponse();
        requset.requestCheck();
        response.setCode(ManagementRetCode.SUCCESS.getCode());
        response.setMsg(ManagementRetCode.SUCCESS.getMessage());

        try {
            SysRole role = new SysRole();
            role.setRoleName(requset.getRoleName());
            if(sysRoleMapper.selectSysRoleByName(role)!=null){
                response.setCode(ManagementRetCode.ROLENAME_ALREADY_EXISTS.getCode());
                response.setMsg(ManagementRetCode.ROLENAME_ALREADY_EXISTS.getMessage());
                return response;
            }
            sysRoleMapper.insert(role);

            if(requset.getMenuIds().size()>0){
                requset.getMenuIds().parallelStream().forEach(dto->{
                    SysRoleMenu sysRoleMenu = new SysRoleMenu();
                    sysRoleMenu.setMenuId(dto);
                    sysRoleMenu.setRoleId(role.getRoleId());
                    sysRoleMenuMapper.insert(sysRoleMenu);
                });
            }
        }catch (Exception e){
            log.info("Begin SysRoleServiceImpl.updateSysRole: request:"+requset);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            response.setCode(ManagementRetCode.SYSTEM_ERROR.getCode());
            response.setMsg(ManagementRetCode.SYSTEM_ERROR.getMessage());
        }
        return response;
    }

    @Override
    public DeleteSysRoleResponse deleteSysRole(DeleteSysRoleRequset requset) {
        log.info("Begin SysRoleServiceImpl.deleteSysRole: request:"+requset);
        DeleteSysRoleResponse response = new DeleteSysRoleResponse();
        requset.requestCheck();
        response.setCode(ManagementRetCode.SUCCESS.getCode());
        response.setMsg(ManagementRetCode.SUCCESS.getMessage());

        try {
            sysRoleMapper.deleteByPrimaryKey(requset.getRoleId());
            sysRoleMenuMapper.deleteByRoleId(requset.getRoleId());
        }catch (Exception e){
            log.info("Begin SysRoleServiceImpl.updateSysRole: request:"+requset);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            response.setCode(ManagementRetCode.SYSTEM_ERROR.getCode());
            response.setMsg(ManagementRetCode.SYSTEM_ERROR.getMessage());
        }
        return response;
    }

    /*@Override
    public InsertRoleMenuResponse insertRoleMenu(InsertRoleMenuRequset requset) {
        log.info("Begin SysRoleServiceImpl.insertRoleMenu: request:"+requset);
        InsertRoleMenuResponse response = new InsertRoleMenuResponse();
        response.setCode(ManagementRetCode.SUCCESS.getCode());
        response.setMsg(ManagementRetCode.SUCCESS.getMessage());

        try {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setMenuId(requset.getMenuId());
            sysRoleMenu.setRoleId(requset.getRoleId());
            sysRoleMenuMapper.insertSelective(sysRoleMenu);
        }catch (Exception e){
            log.info("Begin SysRoleServiceImpl.insertRoleMenu: request:"+requset);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            response.setCode(ManagementRetCode.SYSTEM_ERROR.getCode());
            response.setMsg(ManagementRetCode.SYSTEM_ERROR.getMessage());
        }
        return response;
    }

    @Override
    public UpdateRoleMenuResponse updateRoleMenu(UpdateRoleMenuRequset requset) {
        log.info("Begin SysRoleServiceImpl.deleteSysRole: request:"+requset);
        UpdateRoleMenuResponse response = new UpdateRoleMenuResponse();
        response.setCode(ManagementRetCode.SUCCESS.getCode());
        response.setMsg(ManagementRetCode.SUCCESS.getMessage());

        try {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(requset.getRoleId());
            sysRoleMenu.setMenuId(requset.getMenuId());
            sysRoleMenuMapper.updateByPrimaryKey(sysRoleMenu);
        }catch (Exception e){
            log.info("Begin SysRoleServiceImpl.updateSysRole: request:"+requset);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            response.setCode(ManagementRetCode.SYSTEM_ERROR.getCode());
            response.setMsg(ManagementRetCode.SYSTEM_ERROR.getMessage());
        }
        return response;
    }

    @Override
    public DeleteRoleMenuResponse deleteRoleMenu(DeleteRoleMenuRequset requset) {
        log.info("Begin SysRoleServiceImpl.deleteSysRole: request:"+requset);
        DeleteRoleMenuResponse response  = new DeleteRoleMenuResponse();
        response.setCode(ManagementRetCode.SUCCESS.getCode());
        response.setMsg(ManagementRetCode.SUCCESS.getMessage());

        try {
            sysRoleMenuMapper.deleteByRoleId(requset.getRoleId(),requset.getMenuId());
        }catch (Exception e){
            log.info("Begin SysRoleServiceImpl.updateSysRole: request:"+requset);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            response.setCode(ManagementRetCode.SYSTEM_ERROR.getCode());
            response.setMsg(ManagementRetCode.SYSTEM_ERROR.getMessage());
        }
        return response;
    }*/

    private void validUserRole(SysUser user,SysRole role){
        List<SysRole> roles = sysRoleMapper.selectSysRoleByUserId(user);
        for (SysRole roleEntity: roles){
            if(roleEntity.getRoleId()==role.getRoleId()||
                    roleEntity.getRoleId().equals(role.getRoleId())){
                throw new ValidateException(
                        ManagementRetCode.ROLE_REPEAT_ERROR.getCode(),
                        ManagementRetCode.ROLE_REPEAT_ERROR.getMessage());
            }
        }
    }
}
